﻿using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
using Volo.Abp.DependencyInjection;

namespace Volo.Abp.Sms.Twilio
{
	public class TwilioSmsSender : ISmsSender, ITransientDependency
	{
		protected AbpTwilioSmsOptions Options { get; }

		protected static bool IsTwilioClientInitialized;

		protected static object SyncLock;

		static TwilioSmsSender()
		{
			TwilioSmsSender.SyncLock = new object();
		}

		public TwilioSmsSender(IOptionsSnapshot<AbpTwilioSmsOptions> options)
		{
			Options = options.Value;
			this.InitTwilioClientIfNeeds();
		}

		public virtual async Task SendAsync(SmsMessage smsMessage)
		{
			string text = smsMessage.Text;
			PhoneNumber from = new PhoneNumber(this.Options.FromNumber);
			await MessageResource.CreateAsync(new PhoneNumber(smsMessage.PhoneNumber), null, from, null, text);
		}

		protected virtual void InitTwilioClientIfNeeds()
		{
			if (TwilioSmsSender.IsTwilioClientInitialized)
			{
				return;
			}
			object syncLock = TwilioSmsSender.SyncLock;
			lock (syncLock)
			{
				if (!TwilioSmsSender.IsTwilioClientInitialized)
				{
					this.CheckConfiguration();
					TwilioClient.Init(this.Options.AccountSId, this.Options.AuthToken);
					TwilioSmsSender.IsTwilioClientInitialized = true;
				}
			}
		}

		protected virtual void CheckConfiguration()
		{
			this.CheckOptionNotNullOrWhiteSpace(this.Options.FromNumber, "FromNumber");
			this.CheckOptionNotNullOrWhiteSpace(this.Options.AccountSId, "AccountSId");
			this.CheckOptionNotNullOrWhiteSpace(this.Options.AuthToken, "AuthToken");
		}

		protected virtual void CheckOptionNotNullOrWhiteSpace(string option, string optionName)
		{
			if (option.IsNullOrWhiteSpace())
			{
				throw new AbpException(optionName + "option was not configured! Use AbpTwilioSmsOptions to configure it.");
			}
		}
	}
}
